import tkinter as tk
from tkinter import messagebox, ttk
import random
import time


class AdvancedMinesweeper:
    def __init__(self, master):
        self.master = master
        self.master.title("高级扫雷")
        self.style = ttk.Style()

        # 难度预设
        self.difficulties = {
            "简单": {"rows": 9, "cols": 9, "mines": 10},
            "中等": {"rows": 16, "cols": 16, "mines": 40},
            "困难": {"rows": 16, "cols": 30, "mines": 99},
        }

        self.create_menu()
        self.init_game("简单")

    def create_menu(self):
        menubar = tk.Menu(self.master)
        difficulty_menu = tk.Menu(menubar, tearoff=0)
        for diff in self.difficulties:
            difficulty_menu.add_command(
                label=diff, command=lambda d=diff: self.init_game(d)
            )
        menubar.add_cascade(label="难度", menu=difficulty_menu)
        self.master.config(menu=menubar)

    def init_game(self, difficulty):
        self.difficulty = difficulty
        config = self.difficulties[difficulty]
        self.rows = config["rows"]
        self.cols = config["cols"]
        self.mine_count = config["mines"]
        self.flags_left = self.mine_count
        self.game_over = False
        self.first_click = True
        self.start_time = 0
        self.elapsed_time = 0

        # 清除旧组件
        if hasattr(self, "top_frame"):
            self.top_frame.destroy()
            self.game_frame.destroy()

        self.create_widgets()
        self.create_board()

    def create_widgets(self):
        # 顶部信息栏
        self.top_frame = ttk.Frame(self.master)
        self.top_frame.pack(pady=10)

        self.style.configure("TLabel", font=("Arial", 14))
        self.flag_label = ttk.Label(
            self.top_frame, text=f"🚩: {self.flags_left}", style="TLabel"
        )
        self.flag_label.pack(side=tk.LEFT, padx=20)

        self.time_label = ttk.Label(self.top_frame, text="⏱️: 0", style="TLabel")
        self.time_label.pack(side=tk.RIGHT, padx=20)

        # 游戏网格
        self.game_frame = ttk.Frame(self.master)
        self.game_frame.pack()

        # 创建按钮网格
        self.style.configure("TButton", 
                    width=2,
                    height=1,
                    font=("Arial", 10, "bold"),
                    relief=tk.RAISED
                    )
        self.buttons = []
        for row in range(self.rows):
            button_row = []
            for col in range(self.cols):
                btn = ttk.Button(
                    self.game_frame,
                    # width=2,
                    # height=1,
                    # font=("Arial", 10, "bold"),
                    # relief=tk.RAISED,
                )
                btn.grid(row=row, column=col)
                btn.bind("<Button-1>", lambda e, r=row, c=col: self.left_click(r, c))
                btn.bind("<Button-3>", lambda e, r=row, c=col: self.right_click(r, c))
                button_row.append(btn)
            self.buttons.append(button_row)

    def create_board(self):
        self.board = [[0 for _ in range(self.cols)] for _ in range(self.rows)]
        self.revealed = [[False for _ in range(self.cols)] for _ in range(self.rows)]
        self.flagged = [[False for _ in range(self.cols)] for _ in range(self.rows)]

    def place_mines(self, first_row, first_col):
        mines_placed = 0
        while mines_placed < self.mine_count:
            row = random.randint(0, self.rows - 1)
            col = random.randint(0, self.cols - 1)

            # 确保首次点击位置及周围没有地雷
            if abs(row - first_row) <= 1 and abs(col - first_col) <= 1:
                continue

            if self.board[row][col] != -1:
                self.board[row][col] = -1
                mines_placed += 1

                # 更新周围数字
                for r in range(max(0, row - 1), min(self.rows, row + 2)):
                    for c in range(max(0, col - 1), min(self.cols, col + 2)):
                        if self.board[r][c] != -1:
                            self.board[r][c] += 1

    def left_click(self, row, col):
        if self.game_over or self.flagged[row][col]:
            return

        if self.first_click:
            self.first_click = False
            self.place_mines(row, col)
            self.start_time = time.time()
            self.update_timer()

        if self.board[row][col] == -1:  # 踩雷
            self.game_over = True
            self.reveal_mines()
            messagebox.showinfo("游戏结束", "你踩到地雷了！")
            self.reset_game()
            return

        self.reveal_cell(row, col)
        self.check_win()

    def right_click(self, row, col):
        if self.game_over or self.revealed[row][col]:
            return

        if not self.flagged[row][col] and self.flags_left > 0:
            self.flagged[row][col] = True
            self.style.configure("Red.TButton", fg="red")
            self.buttons[row][col].config(text="🚩", style="Red.TButton")
            self.flags_left -= 1
        elif self.flagged[row][col]:
            self.flagged[row][col] = False
            self.buttons[row][col].config(text="")
            self.flags_left += 1

        self.flag_label.config(text=f"🚩: {self.flags_left}")

    def reveal_cell(self, row, col):
        if (
            row < 0
            or row >= self.rows
            or col < 0
            or col >= self.cols
            or self.revealed[row][col]
            or self.flagged[row][col]
        ):
            return

        self.revealed[row][col] = True
        cell_value = self.board[row][col]

        if cell_value > 0:
            colors = [
                "",
                "blue",
                "green",
                "red",
                "darkblue",
                "brown",
                "teal",
                "black",
                "gray",
            ]
            self.style.configure(
                "CV.TButton",
                fg=colors[cell_value],
                relief=tk.SUNKEN,
            )
            self.buttons[row][col].config(
                text=str(cell_value),
                # fg=colors[cell_value],
                # relief=tk.SUNKEN,
                state=tk.DISABLED,
                style="CV.TButton",
            )
        else:
            self.style.configure(
                "NCV.TButton",
                relief=tk.SUNKEN,
            )
            self.buttons[row][col].config(
                text="",
                # relief=tk.SUNKEN,
                state=tk.DISABLED,
                style="NCV.TButton"
            )
            # 递归揭示空白区域
            for r in range(max(0, row - 1), min(self.rows, row + 2)):
                for c in range(max(0, col - 1), min(self.cols, col + 2)):
                    if r != row or c != col:
                        self.reveal_cell(r, c)

    def reveal_mines(self):
        for row in range(self.rows):
            for col in range(self.cols):
                if self.board[row][col] == -1:
                    self.style.configure(
                        "Mine.TButton", bg="red"
                    )
                    self.buttons[row][col].config(
                        text="💣", style="Mine.TButton", state=tk.DISABLED
                    )

    def check_win(self):
        for row in range(self.rows):
            for col in range(self.cols):
                if self.board[row][col] != -1 and not self.revealed[row][col]:
                    return

        self.game_over = True
        messagebox.showinfo("恭喜", f"你赢了！用时: {self.elapsed_time}秒")
        self.reset_game()

    def update_timer(self):
        if not self.game_over and not self.first_click:
            self.elapsed_time = int(time.time() - self.start_time)
            self.time_label.config(text=f"⏱️: {self.elapsed_time}")
            self.master.after(1000, self.update_timer)

    def reset_game(self):
        self.init_game(self.difficulty)


if __name__ == "__main__":
    root = tk.Tk()
    game = AdvancedMinesweeper(root)
    root.mainloop()
